home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Cream of the Crop 1
/
Cream of the Crop 1.iso
/
PROGRAM
/
UUPC11QS.ARJ
/
SSLEEP.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-10-16
|
8KB
|
181 lines
/*--------------------------------------------------------------------*/
/* s s l e e p . c */
/* */
/* Smart sleep routines for UUPC/extended */
/* */
/* Written by Dave Watts, modified by Drew Derbyshire */
/* */
/* Generates DOS specific code with Windows support by default, */
/* generates call to OS/2 family API if FAMILYAPI is defined */
/*--------------------------------------------------------------------*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <dos.h>
#include "lib.h"
#include "ssleep.h"
#ifdef FAMILYAPI
#define INCL_NOPM
#define INCL_BASE
#include <os2.h>
#include <assert.h>
#else
#include <sys/timeb.h>
#define MULTIPLEX 0x2F
static void GiveUpTimeSlice(void);
static int RunningUnderWindowsWith386(void);
/*--------------------------------------------------------------------*/
/* Use this first to see if the rest are OK */
/* */
/* MOV AX,1600h ; Check for win386/win3.0 */
/* present */
/* INT 2Fh */
/* Return AL = 0 -> No Windows, AL = 80 -> No WIn386 mode */
/* AL = 1 or AL = FFh -> Win386 2.xx running */
/* else AL = Major version (3), AH = Minor version */
/*--------------------------------------------------------------------*/
/* --------------- Release time slice */
/* MOV AX,1680h ; **** Release time slice */
/* INT 2Fh ; Let someone else run */
/* Return code is AL = 80H -> service not installed, AL = 0 -> all */
/* OK */
/*--------------------------------------------------------------------*/
/* --------------- Enter critical section (disable task switch) */
/* MOV AX,1681H ; Don't tread on me! */
/* INT 2Fh */
/*--------------------------------------------------------------------*/
/* --------------- End critical section (Permit task switching) */
/* MOV AX,1682h */
/* INT 2Fh */
/*--------------------------------------------------------------------*/
/*--------------------------------------------------------------------*/
/* R u n n i n g U n d e r W i n d o w s W i t h 3 8 6 */
/* */
/* Easily the longest function name in UUPC/extended. */
/* */
/* Determines if we are running under MS-Windows 386 or */
/* MS-Windows 3. We save the result, to avoid excessively */
/* disabling interrupts when in a spin loop. */
/*--------------------------------------------------------------------*/
static int RunningUnderWindowsWith386(void)
{
static int result = 2;
union REGS inregs, outregs;
int irq;
if (result != 2) /* First call? */
return result; /* No --> Return saved result */
irq = MULTIPLEX;
inregs.x.ax = 0x1600;
int86(irq, &inregs, &outregs);
if ( (outregs.h.al & 0x7f) == 0)
result = 0;
else
result = 1;
return result;
} /* RunningUnderWindowsWith386 */
/*--------------------------------------------------------------------*/
/* G i v e U p T i m e S l i c e */
/* */
/* Surrender our time slice when executing under Windows/386 */
/* or Windows release 3. */
/*--------------------------------------------------------------------*/
static void GiveUpTimeSlice(void)
{
union REGS inregs, outregs;
int irq = MULTIPLEX;
inregs.x.ax = 0x1680;
int86(irq, &inregs, &outregs);
if (outregs.h.al != 0) {
printf("Problem giving up timeslice: %u\n", outregs.h.al);
abort();
}
} /* GiveUpTimeSlice */
#endif
/*--------------------------------------------------------------------*/
/* ssleep() - wait n seconds */
/* */
/* Simply delay until n seconds have passed. */
/*--------------------------------------------------------------------*/
void ssleep(time_t interval)
{
time_t start;
start = time((time_t *)NULL);
while ((time((time_t *)NULL) - start) < interval)
ddelay(1000);
} /*ssleep*/
/*--------------------------------------------------------------------*/
/* d d e l a y */
/* */
/* Delay for an interval of milliseconds */
/*--------------------------------------------------------------------*/
void ddelay (int milliseconds)
{
#ifdef FAMILYAPI
USHORT result = DosSleep(milliseconds);
assert(result == 0);
#else
struct timeb t;
time_t seconds;
unsigned last;
/*--------------------------------------------------------------------*/
/* Handle the special case of 0 delay, which is simply a */
/* request to give up our timeslice */
/*--------------------------------------------------------------------*/
if (milliseconds == 0) /* Make it compatible with DosSleep */
{
if (RunningUnderWindowsWith386())
GiveUpTimeSlice();
return;
} /* if */
ftime(&t); /* Get a starting time */
last = t.millitm; /* Save milliseconds portion */
seconds = t.time; /* Save seconds as well */
while( milliseconds > 0) /* Begin the spin loop */
{
int volatile count; /* Don't let compiler optimize this */
if (RunningUnderWindowsWith386())
GiveUpTimeSlice();
else
for ( count = 0; count < 2400; count ++);
/* We spin so that interrupts are
enabled for most of the loop */
ftime(&t); /* Take a new time check */
if (t.time == seconds) /* Same second as last pass? */
milliseconds -= (t.millitm - last); /* Yes --> mSecond delta*/
else
milliseconds -= 1000 * (int) (t.time - seconds)
- (last - t.millitm);
/* No --> Handle wrap of mSeconds */
last = t.millitm; /* Update last tick indicator */
seconds = t.time; /* Update this as well; only needed if
it changed (see above), but it
kills time (which is our job) */
} /* while */
#endif /* FAMILYAPI */
} /* ddelay */